<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>stringify和parse补充</title>
  <!-- 
  在JavaScript中，JSON.stringify()和JSON.parse()是处理JSON数据的两个基本方法。它们分别用于将JavaScript对象转换为JSON字符串和将JSON字符串解析为JavaScript对象。
  1. JSON.stringify()
  JSON.stringify()方法用于将JavaScript对象或值转换为JSON字符串。
  1.1. 基本用法
  const obj = {
    name: "张三",
    age: 30,
    isStudent: false
  };
  const jsonString = JSON.stringify(obj);
  console.log(jsonString); // 输出: {"name":"张三","age":30,"isStudent":false}

  1.2. 参数
  - value：要序列化的JavaScript值（对象、数组等）。
  - replacer（可选）：可以是一个函数或数组，用于控制哪些值应该被包含在序列化过程中。
  - space（可选）：用于控制输出的格式化（缩进），可以是数字或字符串，表示空格的数量。

  1.3. 示例
  - 使用replacer：
    const obj = { name: "李四", age: 25, password: "123456" };
    const jsonString = JSON.stringify(obj, ["name", "age"]); // 只包含name和age
    console.log(jsonString); // 输出: {"name":"李四","age":25}
  - 使用space进行格式化：
    const obj = { name: "王五", age: 28 };
    const jsonString = JSON.stringify(obj, null, 2); // 使用2个空格缩进
    console.log(jsonString);
    /*
    输出:
    {
      "name": "王五",
      "age": 28
    }
    */
    
  2. JSON.parse()
  JSON.parse()方法用于将JSON字符串解析为JavaScript对象。
  2.1. 基本用法
    const jsonString = '{"name":"张三","age":30,"isStudent":false}';
    const obj = JSON.parse(jsonString);
    console.log(obj); // 输出: { name: '张三', age: 30, isStudent: false }
  2.2. 参数
  - text：要解析的JSON字符串。
  - reviver（可选）：一个函数，用于转换解析后的结果。

  2.3. 示例
  - 使用reviver：
    const jsonString = '{"name":"李四","age":"25"}';
    const obj = JSON.parse(jsonString, (key, value) => {
      if (key === "age") {
        return Number(value); // 将age转换为数字
      }
      return value;
    });
    console.log(obj); // 输出: { name: '李四', age: 25 }
  3. 注意事项
    - 错误处理：在使用JSON.parse()时，如果字符串不是有效的JSON格式，将抛出SyntaxError。因此，通常建议使用try...catch来捕获可能的错误。
    try {
      const obj = JSON.parse('{"name":"张三",age:30}'); // 无效的JSON
    } catch (e) {
      console.error("解析错误:", e.message);
    }
  - 不可序列化的值：JSON.stringify()不能处理undefined、函数、Symbol和特殊对象（如Date、Map、Set等）。这些值在序列化时会被忽略或转换为null。

  - 日期对象：Date对象在序列化时会被转换为ISO 8601格式的字符串，而在解析时会变为字符串，需手动转换为Date对象。
  const date = new Date();
  const jsonString = JSON.stringify({ date });
  const parsed = JSON.parse(jsonString);
  const dateObj = new Date(parsed.date); // 还原为Date对象
  console.log(dateObj); // 输出: 当前日期和时间

  总结
  JSON.stringify()和JSON.parse()是处理JSON数据的核心方法。通过这两个方法，开发者可以方便地在JavaScript对象和JSON字符串之间进行转换，适用于数据存储、网络传输和API交互等场景。
   -->
</head>
<body>

  <script>
    // 1. JSON.stringify()方法
    const obj = { name: "张三", age: 30, address: { city: "北京", street: "长安街" }, fn: function() { return "这是一个自定义方法"; } };

    const obj2 = { name: "张三", age: 30, address: { city: "北京", street: "长安街" }, toJSON: function() { return "这是一个toJSON方法"; } };


    // 1.1. replacer参数
    const jsonString = JSON.stringify(obj, function(key, value) {
      if (key === "age") {
        return 123; 
      }
      return value;
    });
    console.log("JSON.stringify()方法", jsonString); // 有函数会被忽略

    // 1.2 space参数
    const jsonString2 = JSON.stringify(obj, null, 2);
    console.log("JSON.stringify()方法", jsonString2); 

    // 1.3 toJSON方法 - 有toJSON方法会被直接调用
    const jsonString3 = JSON.stringify(obj2);
    console.log("JSON.stringify()方法", jsonString3); // 有toJSON方法会被调用

    // 2. JSON.parse()方法
    const jsonString4 = '{"name":"张三","age":30,"address":{"city":"北京","street":"长安街"},"toJSON":"这是一个toJSON方法"}';
    const parsed = JSON.parse(jsonString4);
    console.log("JSON.parse()方法", parsed);
    
    // 2.1. reviver参数
    const parsed2 = JSON.parse(jsonString4, function(key, value) {
      if (key === "toJSON") {
        return "这是一个自定义方法"; // 将toJSON的值替换为自定义方法
      }
      return value;
    });
    console.log("JSON.parse()方法", parsed2);
    
  </script>
  
</body>
</html>